package com.zxy.supplier_system.server.service

import com.zxy.supplier_system.server.controller.FactoryController
import com.zxy.supplier_system.server.entity.Factory
import com.zxy.supplier_system.server.repository.FactoryRepository
import com.zxy.supplier_system.server.repository.GoodsRepository
import com.zxy.supplier_system.server.repository.SystemServiceRepository
import com.zxy.supplier_system.server.utils.IntIdAndName
import com.zxy.supplier_system.server.utils.orElse404
import org.springframework.data.domain.Page
import org.springframework.data.domain.Pageable
import org.springframework.data.repository.findByIdOrNull
import org.springframework.stereotype.Service
import org.springframework.transaction.annotation.Transactional

@Service
class FactoryService(
    private val factoryRepository: FactoryRepository,
    private val goodsRepository: GoodsRepository,
    private val systemServiceService: SystemServiceService,
    private val employeeOperateRecordService: EmployeeOperateRecordService,
) {


    @Transactional(readOnly = true)
    fun queryFactories(
        pageable: Pageable,
        queryFactoriesRequest: FactoryController.QueryFactoriesRequest
    ): Page<FactoryController.QueryFactoriesResponse> {
        return this.factoryRepository.findAll(
            FactoryRepository.Specifications.fromQueryFactoriesRequest(queryFactoriesRequest).and(
                SystemServiceRepository.Specifications.systemServiceEquals(
                    { root -> root },
                    systemServiceService.getCurrentSystemService()
                )
            ), pageable
        ).map {
            FactoryController.QueryFactoriesResponse(
                it.name,
                it.id,
                this.goodsRepository.countAllByBrand_Factory(it),
                it.contact,
                it.address,
                it.disable,
            )
        }
    }

    @Transactional
    fun updateFactory(id: Int, updateFactoryRequest: FactoryController.UpdateFactoryRequest) {
        val data = this.factoryRepository.findByIdOrNull(id).orElse404()
        data.name = updateFactoryRequest.name
        data.contact = updateFactoryRequest.contact
        data.address = updateFactoryRequest.address
        this.factoryRepository.save(data)
        employeeOperateRecordService.updateFactory(data)
    }

    @Transactional
    fun createFactory(updateFactoryRequest: FactoryController.UpdateFactoryRequest): Factory {
        val factory = this.factoryRepository.save(Factory().apply {
            name = updateFactoryRequest.name
            contact = updateFactoryRequest.contact
            address = updateFactoryRequest.address
            this.systemService = systemServiceService.getCurrentSystemService()
        })
        employeeOperateRecordService.createFactory(factory)
        return factory
    }

    @Transactional
    fun deleteFactory(id: Int) {
        this.factoryRepository.deleteById(id)
    }


    fun getAllFactories(): List<IntIdAndName> {
        return this.factoryRepository.findAllBySystemService(systemServiceService.getCurrentSystemService()).map {
            IntIdAndName(it.id, it.name)
        }
    }

    @Transactional
    fun enable(id: Int) {
        val factory =
            this.factoryRepository.findByIdAndSystemService(id, systemServiceService.getCurrentSystemService())
                .orElse404()
        factory.disable = false
        this.factoryRepository.save(factory)
        this.employeeOperateRecordService.enableFactory(factory)
    }

    @Transactional
    fun disable(id: Int) {
        val factory =
            this.factoryRepository.findByIdAndSystemService(id, systemServiceService.getCurrentSystemService())
                .orElse404()
        factory.disable = true
        this.factoryRepository.save(factory)
        this.employeeOperateRecordService.disableFactory(factory)
    }


}
